package com.zpark.it.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zpark.it.constants.UserConstants;
import com.zpark.it.mapper.UserMapper;
import com.zpark.it.param.PageParam;
import com.zpark.it.param.UserCheckParam;
import com.zpark.it.param.UserLoginParam;
import com.zpark.it.pojo.User;
import com.zpark.it.service.UserService;
import com.zpark.it.utils.MD5Util;
import com.zpark.it.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Title: UserServiceImpl
 * @Author Charles
 * @Package com.zpark.it.service.impl
 * @Date 2023/7/19 22:06
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;
    /**
     * 检查账号是否可用
     * @param userCheckParam 账号参数已经校验完毕，
     * @return 检查接口
     */
    @Override
    public R check(UserCheckParam userCheckParam) {
        //参数封装
        QueryWrapper<User> queryWrapper =new QueryWrapper<>();
        queryWrapper.eq("user_name",userCheckParam.getUserName());
        //数据库查询
        Long total = userMapper.selectCount(queryWrapper);
        //查询结果
        if (total==0){
            //数据库中不存在，可以使用该账号
            log.info("UserServiceImpl.check业务结束，结果：{}","账号可用");
            return R.ok("账号可用使用");
        }
        log.info("UserServiceImpl.check业务结束，结果：{}","账号不可用");
        return R.fail("账号已经存在，不可以使用");
    }

    /**
     * 注册业务
     * 1、检查账号是否存在
     * 2、密码加密处理
     * 3、插入数据库
     * 4、返回结果封装
     * @param user
     * @return
     */
    @Override
    public R register(User user) {
        //1、检查账号是否存在
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_name",user.getUserName());
        //2、数据库查询
        Long total = userMapper.selectCount(queryWrapper);
        if(total>0){
            log.info("UserServiceImpl.register业务完成，结果：{}","账号存在，注册失败");
            return R.fail("账号已经存在");
        }
        //3、密码加密处理
        /**
         *MD5 一种不可逆转加密方式，智能加密不能解密
         *      固定的明文加密以后的密文是固定的
         *      注册是加密以后存密文
         *      登录是加密以后，用密文进行数据库对比
         * MD5可以暴力破解
         */
        String newPwd = MD5Util.encode(user.getPassword() + UserConstants.USER_SLAT);
        user.setPassword(newPwd);

        //4、插入数据库
        int rows = userMapper.insert(user);

        //5、返回结果封装
        if (rows==0){
            log.info("UserServiceImpl.register业务结束，结果：{}","数据插入失败，注册失败");
            return R.fail("注册失败，请稍后再试");
        }
        log.info("UserServiceImpl.register业务结束，结果：{}","注册成功");
        return R.ok("注册成功！");

    }

    /**
     * 登录业务
     *1、密码的加密和加盐处理
     * 2、账号密码进行数据库查询，返回一个完整的数据库user对象
     * 3、判断返回结果
     * @param userLoginParam 账号，密码已经检验，但是密码是明文
     * @return
     */
    @Override
    public R login(UserLoginParam userLoginParam) {
        //1、密码加盐
        String newPwd = MD5Util.encode(userLoginParam.getPassword() + UserConstants.USER_SLAT);
        //2、数据库查询
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_name",userLoginParam.getUserName());

        queryWrapper.eq("password",newPwd);

        User user = userMapper.selectOne(queryWrapper);
        //3、结果处理

        if (user==null){
            log.info("结果：{}","账号或者密码错误");
            return R.fail("账号或者密码错误");
        }
        //不返回password属性
        user.setPassword(null);
        log.info("结果：{}","登录成功");
        return R.ok("登录成功",user);
    }

    /**
     * 后台管理调用查询所有数据
     *
     * @param pageParam
     * @return
     */
    @Override
    public R listPage(PageParam pageParam) {

        IPage<User> page=new Page<>(pageParam.getCurrentPage(),pageParam.getPageSize());

         page = userMapper.selectPage(page, null);

        List<User> records = page.getRecords();

        long total = page.getTotal();

        return R.ok("查询成功",records,total);


    }

    /**
     * 根据用户id删除数据
     *
     * @param userId
     * @return
     */
    @Override
    public R remove(Integer userId) {
        int i = userMapper.deleteById(userId);
        log.info("业务结束：{}",i);
        return R.ok("用户数据删除成功");

    }

    /**
     * 根据用户对象，修改用户信息
     * 1、账号和id不会修改
     * 2、密码需要数据库判断，是不是原来的密码，是就不需要修改
     * 3、如果是新密码需要加密更新
     * 4、修改用户信息
     * @param user
     * @return
     */
    @Override
    public R update(User user) {
        //判断密码是否为原来的
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_id", user.getUserId());
        queryWrapper.eq("password",user.getPassword());
        Long aLong = userMapper.selectCount(queryWrapper);

        if (aLong == null) {
            //明文需要加密
            user.setPassword(MD5Util.encode(user.getPassword()+UserConstants.USER_SLAT));

        }
        int i = userMapper.updateById(user);
        log.info("业务结束：{}",i);

        return R.ok("用户信息修改成功！");
    }

    /**
     * 添加用户信息
     *
     * @param user
     * @return
     */
    @Override
    public R save(User user) {
        //1、检查账号是否存在
        QueryWrapper<User> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("user_name",user.getUserName());
        //2、数据库查询
        Long total = userMapper.selectCount(queryWrapper);
        if(total>0){
            log.info("UserServiceImpl.register业务完成，结果：{}","账号存在，添加失败");
            return R.fail("账号已经存在,不可以添加");
        }
        //3、密码加密处理
        /**
         *MD5 一种不可逆转加密方式，智能加密不能解密
         *      固定的明文加密以后的密文是固定的
         *      注册是加密以后存密文
         *      登录是加密以后，用密文进行数据库对比
         * MD5可以暴力破解
         */
        String newPwd = MD5Util.encode(user.getPassword() + UserConstants.USER_SLAT);
        user.setPassword(newPwd);

        //4、插入数据库
        int rows = userMapper.insert(user);

        //5、返回结果封装
        if (rows==0){
            log.info("UserServiceImpl.register业务结束，结果：{}","数据插入失败，添加失败");
            return R.fail("添加失败，请稍后再试");
        }
        log.info("UserServiceImpl.register业务结束，结果：{}","添加成功");
        return R.ok("添加成功！");

    }
}
